<?php
/**
 * Created by PhpStorm.
 * User: Cui Jun
 * Date: 2016-10-11
 * Time: 9:57
 * To change this template use File | Settings | File Templates.
 */

namespace api\common\controllers;

use api\common\models\Common;
use Yii;
use api\modules\v1\models\ReportStatus;
use yii\rest\ActiveController;
use yii\helpers\ArrayHelper;
use api\cs\RateLimiter;
use yii\web\NotFoundHttpException;
use yii\web\HttpException;
class CommonController extends ActiveController
{

    protected $_is_sign = true; //是否进行登录签名验证
    protected $_is_rate = true; //是否进行速率验证限制

    protected $redis;

   /*
  * @var array
  * 包含分页信息
  */
    public $serializer = [
        'class' => 'yii\rest\Serializer',
        'collectionEnvelope' => 'items',
    ];

    public function beforeAction($action){
        parent::beforeAction($action);
        if($this->_is_sign == true){
            //Sign 签名验证
            $headers = \Yii::$app->request->headers;
            if(empty($headers['DeviceId'])){
                throw new HttpException(401,'DeviceId未找到',0);
            }

            if(empty($headers['Sign'])){
                throw new HttpException(401,'Sign未找到',0);
            }
            $serverSign = md5($headers['DeviceId'].\Yii::$app->params['auth_token_seeds']);
            if($headers['Sign'] != $serverSign){
                throw new HttpException(401,'Sign签名验证失败',0);
            }
        }
        //Sign 签名验证

        //速率验证
        if($this->_is_rate == true){
            $this->rateRedis();
        }
        //速率验证

        $this->checkReportStatus();
        return true;
    }

    /*
     * redis记录ip 防刷
     */
    protected function rateRedis(){
        $DeviceId = $this->getDeviceId();
        if($DeviceId === false){ //如果没有机器码 则使用ip进行速率限制
            $rate_key = \Yii::$app->request->getUserIP();//客户端ip
        }else{
            $rate_key = $DeviceId;//设备唯一编码
        }
        $controller = Yii::$app->controller->id;
        $rate_key = $rate_key.'_'.$controller;

        $rateTime = $this->getRateTime();
        $this->redis = new \Redis();
        $con = $this->redis->connect(Yii::$app->params['redis_hostname'], Yii::$app->params['redis_port'],Yii::$app->params['redis_timeout']);
        if($con){
            $this->redis->select(0);//选择数据库
            if($rate_num = $this->redis->get($rate_key)){
                if($rate_num >= $rateTime[0]){
                    throw new HttpException(401,'放慢脚步,请勿频发操作',0);
                }
                $this->redis->incr($rate_key);//字段增加1
            }else{
                $this->redis->set($rate_key,1,$rateTime[1]);//设置初始值1 设置过期时间
            }
        }
        return true;
    }

    /*
     * 获取设备唯一标识
     * @return array|string
     * @throws HttpException
     */
    public function getDeviceId(){
        $headers = \Yii::$app->request->headers;
        if(!empty($headers['DeviceId'])){
            return $headers['DeviceId'];
        }
        return false;
    }

    /*
    * 获取限制类型
    * @param $action
    * @return string
    */
    protected function getRateTime(){
        $params = \Yii::$app->params['rate'];
        if(isset($params[Yii::$app->controller->id])){
            return Yii::$app->params['rate'][Yii::$app->controller->id];
        }
        return Yii::$app->params['rate']['normal'];
    }


    public function findModel($id)
    {
        $modelClass = $this->modelClass;
        if (($model = $modelClass::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('所请求的数据不存在.');
        }
    }

    /*
     * 检查用户禁言状态
     * @param $uid
     */
    public function checkReportStatus(){
        $commonModel = new Common();
        $user = $commonModel->getTokenUserId();
        if($user !='' && is_array($user)) {
        $uid = $user['id'];
        if($report_status = ReportStatus::findOne(['uid'=>$uid],['type','end_time'])){
            $type = $report_status['type'];//处罚类型 1:禁言 2:封号
            $end_time = $report_status['end_time'];//禁言结束时间
            $route = \Yii::$app->controller->id.'/'.\Yii::$app->controller->action->id;
            if($type == 1){ //禁言
                if(date('Y-m-d H:i:s') < $end_time){ //未过禁言期
                    $forbid = ['publish/news','comment/create']; //发稿、评论
                    if(in_array($route,$forbid)){
                        throw new HttpException(401,'尊敬的用户您好，您因多次违规操作，您的信用积分仅剩'.$user['score'].'分，平台将对您进行禁言一周的处罚，处罚期间您无法正常操作发稿、评论功能，如您对此判定有疑义请致电025-66012899咨询。',0);
                    }
                }
            }elseif($type == 2){ //封号
                $forbid = ['publish/news','comment/create','collect/create']; //发稿、评论、收藏、关注
                if(in_array($route,$forbid)){
                    throw new HttpException(401,'尊敬的用户您好，您因多次违规操作，您的信用积分已被扣除，平台将对您进行封号处罚，您的帐号将无法正常操作发稿、评论、收藏、关注等所有功能，如您对此判定有疑义请致电025-66012899咨询。',0);
                }
            }
        }
    }
  }

}